#include <bits/stdc++.h>
using namespace std;
struct Point {
    int d, count;
} pb[100005];
int da[100005], va[100005], aa[100005], ea[100005], pa[100005], ca[100005];
bool f[100005];
int main() {
    freopen("detect.in", "r", stdin);
    freopen("detect.out", "w", stdout);
    int t;
    scanf("%d", &t);
    while (t--) {
        int n, m, l, v, ans1=0, ans2=0;
        scanf("%d%d%d%d", &n, &m, &l, &v);
        bool ab = true;
        for (int i=0; i<n; i++) {
            scanf("%d%d%d", &da[i], &va[i], &aa[i]);
            if (aa[i]<0) ab = false;
            ca[i] = 0;
        }
        for (int i=0; i<m; i++) {
            scanf("%d", &pa[i]);
            pb[i].d = pa[i];
        }
        for (int i=0; i<n; i++) {
            f[i] = false;
            if (aa[i] > 0) {
                if (va[i] <= v)
                    da[i] += (v * v - va[i] * va[i]) / (2 * aa[i]) + 1;
                if (da[i] <= pa[m-1]) {
                    ans1++;
                    f[i] = true;
                }
                ea[i] = l+1;
            } else if (aa[i] == 0) {
                if (va[i] > v && da[i] <= pa[m-1]) {
                    ans1++;
                    f[i] = true;
                }
                ea[i] = l+1;
            } else {
                if (va[i] > v) {
                    ea[i] = da[i] + ceil((v * v - va[i] * va[i]) * 1.0 / (2 * aa[i]));
                    int j = lower_bound(pa, pa+m, ea[i]) - pa - 1;
                    if (j >= 0 && pa[j] >= da[i]) {
                        ans1++;
                        f[i] = true;
                    }
                } else ea[i] = 0;
            }
        }
        if (ab) {
            ans2 = (ans1 == 0 ? m : m-1);
        } else if (n <= 20) {
            bool ok[n+5];
            for (int i=0; i<(1<<m)-1; i++) {
                int p = 0, cur = m;
                for (int j=0; j<n; j++) ok[j] = false;
                for (int k=0; k<m; k++)
                    if ((1<<k) & i) {
                        for (int j=0; j<n; j++)
                            if (!ok[j] && f[j] && da[j] <= pb[k].d && ea[j] > pb[k].d) {
                                ok[j] = true;
                                p++;
                            }
                        cur--;
                    }
                if (p<ans1) continue;
                ans2 = max(ans2, cur);
            }
        } else {
            for (int i=0; i<m; i++) {
                pb[i].count = 0;
                for (int j=0; j<n; j++)
                    if (f[j] && da[j] <= pb[i].d && ea[j] > pb[i].d) {
                        pb[i].count++;
                        ca[j]++;
                    }
            }
            sort(pb, pb+m, [](Point x, Point y) {return x.count < y.count;});
            for (int i=0; i<m; i++) {
                bool ok = true;
                for (int j=0; j<n; j++)
                    if (f[j] && da[j] <= pb[i].d && ea[j] > pb[i].d && ca[j] <= 1) {
                        ok = false;
                        break;
                    }
                if (!ok) continue;
                ans2++;
                for (int j=0; j<n; j++)
                    if (f[j] && da[j] <= pb[i].d && ea[j] > pb[i].d)
                        ca[j]--;
            }
        }
        printf("%d %d\n", ans1, ans2);
    }
    return 0;
}